#include "LinkQueue.h"
#include "LinkStack.h"
#include <stdio.h>
#include <stdlib.h>
#include <MyString.h>

#define StopSize 3

struct Car
{
    MyStr name;
    double arrveTime;
    double leaveTime;
};
typedef struct Car car;

car* CreateCar(const char *name, double arriveTime)
{
    car *newCar = (car*)malloc(sizeof(car));
    if (newCar == NULL)
    {
        printf("CreateCar error!\n");
        return 0;
    }
    InitString(&newCar->name);
    newCar->name.InsertString(&newCar->name, name);
    newCar->arrveTime = arriveTime;
    return newCar;
}

void FreeCar(car *c)
{
    if (c == NULL)
    {
        return;
    }
    c->name.ClearString(&c->name);
    free(c);
}

void PrintCar(void *value)
{
    car *c = (car *)value;
    printf("车牌：|%s|, 到达时间：|%lf|\n", c->name.str, c->arrveTime);
}

void ComeCar(LStack *carStop, LQueue *pavement)
{
    char name[100] = {0};
    printf("请输入车牌号:");
    scanf("%s", name);
    printf("请输入到达时间:");
    double arriveTime;
    scanf("%lf", &arriveTime);

    car *c = CreateCar(name, arriveTime);
    if (c == NULL)
    {
        printf("创建车辆失败!\n");
        return;
    }

    if (GetStackLen(carStop) < StopSize)
    {
        SPush(carStop, c);
        printf("当前停车场未停满，车辆|%s|进入停车场，到达时间是|%lf|，停在|%d|的位置\n", c->name.str, c->arrveTime, GetStackLen(carStop));
    }
    else
    {
        QPush(pavement, c);
        printf("当前停车场已停满，车辆|%s|进入便道，停在|%d|的位置\n", c->name.str, GetQueueLen(pavement));
    }

}

void LeaveCar(LStack *carStop, LQueue *pavement)
{
    char name[100] = {0};
    printf("请输入要离开的汽车车牌：");
    scanf("%s", name);
    // 定义一个临时栈
    LStack temp;
    InitLStack(&temp);

    double leaveTime = 0.0;
    while (IsStackEmpty(carStop) == false)
    {
        car *c = (car*)*GetTop(carStop);
        SPop(carStop);
        InsertMyStr(str, name);
        if (c->name.IsStringEqual(&c->name, &str) == true)
        {
            printf("请输入汽车的离场时间：");
            scanf("%lf", &c->leaveTime);
            leaveTime = c->leaveTime;
            printf("车辆|%s|将要离场，到达时间是|%lf|, 离开时间是|%lf|, 停车费用是|%lf|\n", c->name.str, c->arrveTime, c->leaveTime, (c->leaveTime - c->arrveTime) * 5);
            FreeCar(c);
            str.ClearString(&str);
            break;
        }
        SPush(&temp, c);
    }
    while (IsStackEmpty(&temp) == false)
    {
        SPush(carStop, *GetTop(&temp));
        SPop(&temp);
    }
    if (GetStackLen(carStop) < StopSize)
    {
        if (IsLQueueEmpty(pavement) == false)
        {
            car *c = (car*)*GetLQueueFront(pavement);
            QPop(pavement);
            c->arrveTime = leaveTime;
            SPush(carStop, c);
            printf("便道上的|%s|进入了停车场，时间是|%lf|\n", c->name.str, c->arrveTime);
        }
    }
    else
    {
        printf("输入的车牌没有找到\n");
    }
}

void DisplayCarStop(LStack *carStop)
{
    Travel(&carStop->list, PrintCar);
}

void DisplayPavement(LQueue *pavement)
{
    TravelDCList(&pavement->list.dllist, PrintCar);
}

int main()
{
    LStack carStop;
    InitLStack(&carStop);

    LQueue pavement;
    InitLinkQueue(&pavement);

    int choice = 0;
    while (1)
    {
        printf("============================停车场=========================\n");
        printf("1、车辆进入停车场\n");
        printf("2、车辆离开停车场\n");
        printf("3、显示停车场和便道信息\n");
        printf("4、退出系统\n");

        scanf("%d", &choice);

        switch (choice)
        {
        case 1:
            ComeCar(&carStop, &pavement);
            break;
        case 2:
            LeaveCar(&carStop, &pavement);
            break;
        case 3:
            printf("=======停车场信息=======\n");
            DisplayCarStop(&carStop);
            printf("=======便道信息=======\n");
            DisplayPavement(&pavement);
            break;
        case 4:
            printf("感谢使用本系统\n");
            return;
        default:
            break;
        }
    }
    return 0;
}
